package slave

import (
	"backend/internal/common/errorx"
	"backend/internal/db/model"
	"backend/internal/svc"
	"backend/internal/types"
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"net/http"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetSlaveTableLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetSlaveTableLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetSlaveTableLogic {
	return &GetSlaveTableLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetSlaveTableLogic) GetSlaveTable(req *types.SlaveInfo) (resp *types.SlaveTableResponse, err error) {
	// 查找设备
	var device model.Device
	err = l.svcCtx.GormDB.Where("name = ?", req.DeviceName).First(&device).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			errorStr := fmt.Sprintf("设备 %s 不存在", req.DeviceName)
			logx.Errorf(errorStr)
			return nil, errors.New(errorStr)
		}
		errorStr := fmt.Sprintf("查询设备 %s 失败: %v", req.DeviceName, err)
		logx.Errorf(errorStr)
		return nil, errors.New(errorStr)
	}

	// 查找从站
	var slave model.Slave
	err = l.svcCtx.GormDB.Where("device_id = ? AND slave_id = ?", device.ID, req.SlaveId).First(&slave).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			errorStr := fmt.Sprintf("设备 %s 下从站 %d 不存在", req.DeviceName, req.SlaveId)
			logx.Errorf(errorStr)
			return nil, errorx.NewDefaultError(errorStr)
		}
		errorStr := fmt.Sprintf("查询设备 %s 下从站 %d 失败: %v", req.DeviceName, req.SlaveId, err)
		logx.Errorf(errorStr)
		return nil, errorx.NewDefaultError(errorStr)
	}

	// 查找寄存器
	var register model.Register
	err = l.svcCtx.GormDB.Where("slave_id = ? AND register_type = ?", slave.SlaveID, req.RegisterType).First(&register).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			errorStr := fmt.Sprintf("设备: %s 从站: %d 未配置寄存器地址, 查询失败!", req.DeviceName, req.SlaveId)
			logx.Errorf(errorStr)
			return nil, errorx.NewDefaultError(errorStr)
		}
		errorStr := fmt.Sprintf("获取从站地址失败: %v", err)
		logx.Errorf(errorStr)
		return nil, errorx.NewDefaultError(errorStr)
	}

	resp = &types.SlaveTableResponse{
		Status: http.StatusOK,
		Msg:    "获取从站寄存器表成功",
		Data:   []int{},
	}
	for i := register.StartAddress; i <= register.EndAddress; i++ {
		resp.Data = append(resp.Data, int(i))
	}
	return resp, nil
}
